package com.soboot.system.biz;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.soboot.base.util.SecurityUtil;
import com.soboot.system.common.DataConstant;
import com.soboot.system.entity.SysMenu;
import com.soboot.system.mapper.SysMenuMapper;
import com.soboot.system.service.ISysMenuService;
import com.soboot.system.vo.MetaVO;
import com.soboot.system.vo.QueryMenuListVO;
import com.soboot.system.vo.RouteVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author:
 * @createTime: 2022年11月17日 22:37:07
 * @version:
 * @Description:
 * @Copyright:
 */
@Component
public class UserServiceBiz {

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private SysMenuMapper menuMapper;

    public Map<String, Object> routes(){
        String userId= SecurityUtil.getUserId();
        Map<String, Object> map = new HashMap<>();
        List<String> perms = new ArrayList<>();
        List<RouteVO> routes = new ArrayList<>();
        List<SysMenu> menuEntitys = menuMapper.selectMenuByUserId(userId);
        if(CollUtil.isNotEmpty(menuEntitys)){
            Set<String> permSet = menuEntitys.stream()
                    .filter(menuEntity -> StrUtil.isNotBlank(menuEntity.getMenuPerms()))
                    .map(SysMenu::getMenuPerms)
                    .collect(Collectors.toSet());
            perms = new ArrayList<>(permSet);
            List<SysMenu> menus = menuEntitys.stream().filter(menuEntity -> DataConstant.MenuType.MODULE.getKey().equals(menuEntity.getMenuType())
                            || DataConstant.MenuType.MENU.getKey().equals(menuEntity.getMenuType()))
                    .collect(Collectors.toList());
            routes = getRouteTree(menus, 0);
        }
        map.put("perms", perms);
        map.put("routes", routes);
        return map;
    }

    public static List<RouteVO> getRouteTree(List<SysMenu> list, Integer pid){
        List<RouteVO> result = new ArrayList<>();
        List<RouteVO> temp;
        for(SysMenu entity : list){
            if(entity.getParentId().equals(pid)){
                MetaVO metaVo = new MetaVO();
                metaVo.setIcon(entity.getMenuIcon());
                metaVo.setTitle(entity.getMenuName());
                RouteVO routeVo = new RouteVO();
                routeVo.setName(entity.getMenuName());
                routeVo.setComponent(entity.getMenuComponent());
                routeVo.setPath(entity.getMenuPath());
                routeVo.setRedirect(entity.getMenuRedirect());
                routeVo.setMeta(metaVo);
                routeVo.setHidden(DataConstant.TrueOrFalse.TRUE.getKey().equals(entity.getMenuHidden()));
                temp = getRouteTree(list, entity.getId());
                if(CollUtil.isNotEmpty(temp)){
                    routeVo.setChildren(temp);
                }
                result.add(routeVo);
            }
        }
        return result;
    }

    public Map<String, Object> routesV2(){
        String userId= SecurityUtil.getUserId();
        List<QueryMenuListVO> result = sysMenuService.getListByUserId(Integer.valueOf(userId));

        List<QueryMenuListVO> trees = result.stream().filter(t->0 == t.getParentId())
                .map((menu)->{
                    menu.setChildren(getChildren(menu,result));
                    return menu;
                }).sorted((menu1,menu2)->{return (menu1.getOrderNum()==null?0:menu1.getOrderNum())-(menu2.getOrderNum()==null?0:menu2.getOrderNum());})
                .collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        if(!CollectionUtils.isEmpty(trees)) {
            map.put("routes", trees);
        }

        Set<String> perms = result.stream().map(QueryMenuListVO::getPerms).collect(Collectors.toSet());
        if(!CollectionUtils.isEmpty(perms)) {
            map.put("perms", perms);
        }
        return map;
    }

    private List<QueryMenuListVO> getChildren(QueryMenuListVO current,List<QueryMenuListVO> all){
        List<QueryMenuListVO> childs = all.stream()
                .filter(t->t.getParentId() == current.getId())
                .map(p->{
                    p.setChildren(getChildren(p,all));
                    return p;
                }).sorted((menu1,menu2)->{return (menu1.getOrderNum()==null?0:menu1.getOrderNum())-(menu2.getOrderNum()==null?0:menu2.getOrderNum());})
                .collect(Collectors.toList());

        return childs;
    }
}
